// 上行管理
package api

import (
	"net"
	db "slgw_web/application/gormdb"
	"slgw_web/serial/pac"
	"strconv"
	"strings"
	"time"

	"gorm.io/gorm/clause"
	"openzbox.com/frame/echo"
	models "openzbox.com/frame/echo/models/sl_gw01"
	"openzbox.com/frame/echo/response"
)

func GetDeviceInfo(ctx echo.Context) error {
	Serial := []models.Serial{}
	db := db.GetDB()
	var CollectNameList []models.CollectNameList //所有的采集点名称
	systemInfo := models.SystemInfo{}
	db.First(&systemInfo)
	comType := 1
	if systemInfo.ID != 0 {
		comType = systemInfo.ComType
	}
	//查询所有文章,以及文章的分类Preload
	db.Preload("Serial_Slave").Preload("Serial_Slave.Serial_Slave_Detail").Find(&Serial)
	for _, data := range Serial {
		for _, data2 := range data.Serial_Slave {
			for i := range data2.Serial_Slave_Detail {
				if data2.Serial_Slave_Detail[i].Serial_ID == data.ID && data2.Serial_Slave_Detail[i].Serial_Slave_ID == data2.ID {
					var s models.CollectNameList
					describe := pac.GetCOMName(data.ComName, comType) + "." + data2.Name + "." + data2.Serial_Slave_Detail[i].Name
					s.CollectName = describe
					s.Serial_Slave_Detail_ID = data2.Serial_Slave_Detail[i].ID
					CollectNameList = append(CollectNameList, s)
				}

			}
		}
	}

	deviceInfo := []models.DeviceInfo{}
	// sql := db.Debug().Preload("DeviceInfo_Concentrator").Preload("DeviceInfo_Concentrator.DeviceInfo_Concentrator_User").
	// 	Preload("DeviceInfo_Concentrator_User.DeviceInfo_Detail").Preload("DeviceInfo_Detail").Find(&deviceInfo).Statement.SQL.String()
	// db.Preload("DeviceInfo_Concentrator.DeviceInfo_Concentrator_User.DeviceInfo_Detail").Preload("DeviceInfo_Detail").Find(&deviceInfo)
	db.Preload("DeviceInfo_Concentrator.DeviceInfo_Concentrator_User").Preload("DeviceInfo_Detail").Find(&deviceInfo)
	for _, d1 := range deviceInfo {
		// if d1.ApplicationLayerProtocol == 6 {
		// 	//四表协议
		// 	for _, c := range d1.DeviceInfo_Concentrator {
		// 		for _, u := range c.DeviceInfo_Concentrator_User {
		// 			for i := range u.DeviceInfo_Detail {
		// 				for _, d3 := range CollectNameList {
		// 					if u.DeviceInfo_Detail[i].Serial_Slave_Detail_ID == d3.Serial_Slave_Detail_ID {
		// 						u.DeviceInfo_Detail[i].CollectName = &d3.CollectName
		// 						break // 在找到匹配的 CollectName 后，立即退出当前循环，避免赋值多次
		// 					}
		// 				}
		// 			}
		// 		}
		// 	}
		// } else {
		for i := range d1.DeviceInfo_Detail {
			for _, d3 := range CollectNameList {
				if d1.DeviceInfo_Detail[i].Serial_Slave_Detail_ID == d3.Serial_Slave_Detail_ID {
					d1.DeviceInfo_Detail[i].CollectName = &d3.CollectName
					break // 在找到匹配的 CollectName 后，立即退出当前循环，避免赋值多次
				} else if d1.DeviceInfo_Detail[i].Serial_ID == -1 {
					CollectName := "时间戳.秒"
					d1.DeviceInfo_Detail[i].CollectName = &CollectName
				} else if d1.DeviceInfo_Detail[i].Serial_ID == -2 {
					CollectName := "时间戳.毫秒"
					d1.DeviceInfo_Detail[i].CollectName = &CollectName
				}
			}
		}
		//}
	}
	return response.SuccessResult(deviceInfo, ctx)

}

// 修改上报属性
func EditDeviceInfo(ctx echo.Context) error {
	var req models.EditDeviceInfoRequest
	if err := ctx.Bind(&req); err != nil {
		// 处理参数绑定错误
		//	ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return response.FailResult(1, err.Error(), ctx)

	}
	// _, err := net.DialTimeout("tcp", req.DeviceInfo.IP+":"+req.DeviceInfo.PORT, 1*time.Second)
	// if err != nil {
	// 	return response.FailResult(1, "TCP连接失败,请检查地址和端口:"+err.Error(), ctx)
	// }
	db := db.GetDB()
	if req.DeviceInfo.ID != 0 {
		//修改
		// if req.DeviceInfo.ApplicationLayerProtocol == 3 {
		// 	var deviceInfo []models.DeviceInfo
		// 	db.Where("ApplicationLayerProtocol=?", req.DeviceInfo.ApplicationLayerProtocol).Find(&deviceInfo)
		// 	if len(deviceInfo) > 1 {
		// 		return response.FailResult(1, "当前协议只能创建一个", ctx)
		// 	} else if len(deviceInfo) == 1 {
		// 		if deviceInfo[0].ID != req.DeviceInfo.ID {
		// 			return response.FailResult(1, "当前协议只能创建一个", ctx)
		// 		}
		// 	}
		// }

		//协议如果改变，需要把原本detail对应数据删除
		delete := false
		var deviceInfo models.DeviceInfo
		db.Where("ID=?", req.DeviceInfo.ID).Find(&deviceInfo)
		if deviceInfo.ID == 0 {
			return response.FailResult(1, "数据不存在", ctx)
		} else {
			if deviceInfo.ApplicationLayerProtocol != req.DeviceInfo.ApplicationLayerProtocol { //判断协议是否改变
				delete = true
			}
		}
		if err := db.Model(&models.DeviceInfo{}).Where("id = ?", req.DeviceInfo.ID).Updates(req.DeviceInfo).Error; err != nil {
			// 处理更新错误
			return response.FailResult(1, err.Error(), ctx)

		}
		if delete { //协议出现变化需要删除对应详情数据
			db.Where("Device_ID = ?", req.DeviceInfo.ID).Delete(&models.DeviceInfo_Detail{})
			if deviceInfo.ApplicationLayerProtocol == 6 {
				//四表协议
				db.Where("Device_ID = ?", req.DeviceInfo.ID).Delete(&models.DeviceInfo_Concentrator{})
				db.Where("Device_ID = ?", req.DeviceInfo.ID).Delete(&models.DeviceInfo_Concentrator_User{})
			}
		}

	} else {
		//新增
		// if req.DeviceInfo.ApplicationLayerProtocol == 3 {
		// 	var deviceInfo []models.DeviceInfo
		// 	db.Where("ApplicationLayerProtocol=?", req.DeviceInfo.ApplicationLayerProtocol).Find(&deviceInfo)
		// 	if len(deviceInfo) > 0 {
		// 		return response.FailResult(1, "当前协议只能创建一个", ctx)
		// 	}
		// }
		if err := db.Create(&req.DeviceInfo).Error; err != nil {
			return response.FailResult(1, err.Error(), ctx)

		}
	}
	return response.SuccessResultWithEmptyData(ctx)
}

// 修改集中器配置
func EditDeviceInfo_Concentrator(ctx echo.Context) error {
	var req models.EditDeviceInfo_ConcentratorRequest
	if err := ctx.Bind(&req); err != nil {
		// 处理参数绑定错误
		return response.FailResult(1, err.Error(), ctx)

	}
	db := db.GetDB()
	if req.DeviceInfo_Concentrator.ID != 0 {

		if err := db.Model(&models.DeviceInfo_Concentrator{}).Where("id = ?", req.DeviceInfo_Concentrator.ID).Updates(req.DeviceInfo_Concentrator).Error; err != nil {
			// 处理更新错误
			return response.FailResult(1, err.Error(), ctx)

		}

	} else {
		//新增
		if err := db.Create(&req.DeviceInfo_Concentrator).Error; err != nil {
			return response.FailResult(1, err.Error(), ctx)

		}
	}
	return response.SuccessResultWithEmptyData(ctx)
}

// 修改集中器-用户表配置
func EditDeviceInfo_Concentrator_User(ctx echo.Context) error {
	var req models.EditDeviceInfo_Concentrator_UserRequest
	if err := ctx.Bind(&req); err != nil {
		// 处理参数绑定错误
		return response.FailResult(1, err.Error(), ctx)

	}
	db := db.GetDB()
	if req.DeviceInfo_Concentrator_User.ID != 0 {

		if err := db.Model(&models.DeviceInfo_Concentrator_User{}).Where("id = ?", req.DeviceInfo_Concentrator_User.ID).Updates(req.DeviceInfo_Concentrator_User).Error; err != nil {
			// 处理更新错误
			return response.FailResult(1, err.Error(), ctx)

		}

	} else {
		//新增
		if err := db.Create(&req.DeviceInfo_Concentrator_User).Error; err != nil {
			return response.FailResult(1, err.Error(), ctx)

		}
	}
	return response.SuccessResultWithEmptyData(ctx)
}

// 暂无用 把数据转为map格式
// func structToMap(s interface{}) map[string]interface{} {
// 	result := make(map[string]interface{})
// 	v := reflect.ValueOf(s)

// 	if v.Kind() == reflect.Ptr {
// 		v = v.Elem()
// 	}

// 	typeOfS := v.Type()
// 	for i := 0; i < v.NumField(); i++ {
// 		field := v.Field(i)
// 		fieldName := typeOfS.Field(i).Name
// 		result[fieldName] = field.Interface()
// 	}

// 	return result
// }

// 删除上报属性
func DeleteDeviceInfo(ctx echo.Context) error {
	deviceInfolID := ctx.FormValue("DeviceInfolID")
	//serial := models.Serial{}
	id, _ := strconv.ParseInt(deviceInfolID, 10, 64)
	deviceInfo := &models.DeviceInfo{ID: id}
	db := db.GetDB()
	if err := db.Select(clause.Associations).Delete(&deviceInfo).Error; err != nil {
		return response.FailResult(1, err.Error(), ctx)

	}
	return response.SuccessResultWithEmptyData(ctx)
}

// 删除集中器配置
func DeleteConcentrator(ctx echo.Context) error {
	concentratorID := ctx.FormValue("ConcentratorID")
	//serial := models.Serial{}
	id, _ := strconv.ParseInt(concentratorID, 10, 64)
	concentrator := &models.DeviceInfo_Concentrator{ID: id}
	db := db.GetDB()
	if err := db.Select(clause.Associations).Delete(&concentrator).Error; err != nil {
		return response.FailResult(1, err.Error(), ctx)

	}
	if err := db.Where("DeviceInfo_Concentrator_ID = ?", id).Delete(&models.DeviceInfo_Detail{}).Error; err != nil {
		return response.FailResult(1, err.Error(), ctx)

	}
	return response.SuccessResultWithEmptyData(ctx)
}

// 删除集中器-用户表配置
func DeleteConcentratorUser(ctx echo.Context) error {
	concentratorUserID := ctx.FormValue("ConcentratorUserID")
	//serial := models.Serial{}
	id, _ := strconv.ParseInt(concentratorUserID, 10, 64)
	concentratorUser := &models.DeviceInfo_Concentrator_User{ID: id}
	db := db.GetDB()
	if err := db.Select(clause.Associations).Delete(&concentratorUser).Error; err != nil {
		return response.FailResult(1, err.Error(), ctx)

	}
	return response.SuccessResultWithEmptyData(ctx)
}

// 修改上报配置（详情）
func EditDeviceInfoDetail(ctx echo.Context) error {
	var ss models.EditDeviceInfoDetailRequest
	if err := ctx.Bind(&ss); err != nil {
		// 处理参数绑定错误
		//	ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return response.FailResult(1, err.Error(), ctx)

	}
	db := db.GetDB()
	var addData models.EditDeviceInfoDetailRequest
	for _, req := range ss.DeviceInfo_Detail {
		if req.ID != 0 {
			//修改
			// if err := db.Model(&models.DeviceInfo_Detail_Table{}).Where("ID = ?", req.ID).Updates(req).Error; err != nil {
			// 	// 处理更新错误
			// 	return response.FailResult(1, err.Error(), ctx)
			// }
			if err := db.Save(&req).Error; err != nil {
				return response.FailResult(1, err.Error(), ctx)
			}
		} else {
			//新增
			// if err := db.Create(&req).Error; err != nil {
			// 	return response.FailResult(1, err.Error(), ctx)

			// }
			addData.DeviceInfo_Detail = append(addData.DeviceInfo_Detail, req)
		}
	}
	//新增
	if len(addData.DeviceInfo_Detail) != 0 {
		if err := db.Create(&addData.DeviceInfo_Detail).Error; err != nil {
			return response.FailResult(1, err.Error(), ctx)

		}
	}
	return response.SuccessResultWithEmptyData(ctx)
}

// 删除上报配置(详情)
func DeleteDeviceInfoDetail(ctx echo.Context) error {
	deviceInfoDetailID := ctx.FormValue("DeviceInfoDetailID")
	//serial := models.Serial{}
	id, _ := strconv.ParseInt(deviceInfoDetailID, 10, 64)
	deviceInfoDetail := &models.DeviceInfo_Detail_Table{ID: id}
	db := db.GetDB()
	if err := db.Select(clause.Associations).Delete(&deviceInfoDetail).Error; err != nil {
		return response.FailResult(1, err.Error(), ctx)

	}
	return response.SuccessResultWithEmptyData(ctx)
}

// 下拉框获取通道信息
func GetSelectSerialInfo(ctx echo.Context) error {
	Serial := []models.Serial{}
	db := db.GetDB()
	systemInfo := models.SystemInfo{}
	db.First(&systemInfo)
	comType := 1
	if systemInfo.ID != 0 {
		comType = systemInfo.ComType
	}
	db.Preload("Serial_Slave").Preload("Serial_Slave.Serial_Slave_Detail").Find(&Serial)
	for _, data := range Serial {
		for _, data2 := range data.Serial_Slave {
			for i := range data2.Serial_Slave_Detail {
				if data2.Serial_Slave_Detail[i].Serial_ID == data.ID && data2.Serial_Slave_Detail[i].Serial_Slave_ID == data2.ID {
					describe := pac.GetCOMName(data.ComName, comType) + "." + data2.Name + "." + data2.Serial_Slave_Detail[i].Name
					data2.Serial_Slave_Detail[i].CollectName = &describe
				}

			}
		}
	}
	outputData := transformData(Serial)
	// if len(outputData) == 1 {
	// 	outputData = outputData[0].Children
	// }
	for _, node := range outputData {
		groupNodesByType(node)
	}
	outputDatas := flattenNestedLevel(outputData)

	return response.SuccessResult(outputDatas, ctx)
}

func transformData(inputData []models.Serial) []*models.OutputData {
	var transformedData []*models.OutputData
	// 将数据转换为目标结构
	systemInfo := models.SystemInfo{}
	db := db.GetDB()
	db.First(&systemInfo)
	comType := 1
	if systemInfo.ID != 0 {
		comType = systemInfo.ComType
	}
	for _, item1 := range inputData {
		var children []*models.OutputData
		for _, item2 := range item1.Serial_Slave {
			var children2 []*models.OutputData
			for _, item3 := range item2.Serial_Slave_Detail {
				children2 = append(children2, &models.OutputData{
					Title:           *item3.CollectName,
					ID:              strconv.FormatInt(item3.ID, 10),
					Type:            strconv.FormatInt(item3.Type, 10),
					Serial_ID:       item1.ID,
					Serial_Slave_ID: item2.ID,
				})
			}
			children = append(children, &models.OutputData{
				Title:    item2.Name,
				ID:       "2-" + strconv.FormatInt(item2.ID, 10), //guid.GUID(), //item2.ID,
				Type:     "-1",
				Children: children2,
			})
		}
		transformedData = append(transformedData, &models.OutputData{
			Title:    pac.GetCOMName(item1.ComName, comType),
			ID:       "3-" + strconv.FormatInt(item1.ID, 10), //guid.GUID(), // item1.ID,
			Type:     "-1",
			Children: children,
		})
	}
	return transformedData
}

func groupNodesByType(node *models.OutputData) *models.OutputData {
	if node == nil {
		return nil
	}

	// Recursively process children first
	for _, child := range node.Children {
		groupNodesByType(child)
	}

	// Group children by type
	typeMap := make(map[string][]*models.OutputData)
	for _, child := range node.Children {
		typeMap[child.Type] = append(typeMap[child.Type], child)
	}

	node.Children = nil
	for _, children := range typeMap {
		groupedNode := &models.OutputData{
			Title:    Gettitle(children[0].Type), //children[0].Title,
			ID:       "3-" + children[0].ID,
			Type:     children[0].Type,
			Children: children,
		}
		node.Children = append(node.Children, groupedNode)
		if len(children) == 1 {
			for _, item2 := range children {
				if item2.Title == "错误" || strings.Contains(item2.Title, "功能码") {
					node.Children = append(node.Children, children[0])
				}
			}

		}
	}

	return node
}

func Gettitle(Type string) string {
	switch Type {
	case "0":
		{
			return "采集"
		}
	case "1":
		{
			return "功能码1"
		}
	case "2":
		{
			return "功能码2"
		}
	case "3":
		{
			return "功能码3"
		}
	case "4":
		{
			return "功能码4"
		}
	case "10":
		{
			return "点表"
		}
	default:
		{
			return "错误"
		}
	}
}

// 删除指定层级
func flattenNestedLevel(arr []*models.OutputData) []*models.OutputData {
	var result []*models.OutputData
	for _, data := range arr {
		if len(data.Children) > 0 && len(data.Children[0].Children) > 0 {
			flattenedData := &models.OutputData{
				Title:    data.Title,
				Type:     data.Type,
				Children: data.Children[0].Children,
				ID:       data.ID,
			}
			result = append(result, flattenedData)
		} else {
			result = append(result, data)
		}

	}
	return result
}

// 判断tcp连接是否成功
func GetTcpConnect(ctx echo.Context) error {
	IP := ctx.FormValue("IP")
	if IP == "" {
		return response.FailResult(1, "参数必填", ctx)
	}
	_, err := net.DialTimeout("tcp", IP, 1*time.Second)
	if err != nil {
		return response.FailResult(1, "连接失败:"+err.Error(), ctx)
	} else {
		return response.SuccessResult("连接成功", ctx)
	}

}
